package com.xiaotao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.xiaotao.dto.*;
//import com.xiaotao.entity.GroupBuy;
import com.xiaotao.entity.*;
//import com.xiaotao.mapper.GroupBuyMapper;
import com.xiaotao.mapper.*;
import com.xiaotao.publisher.CustomPublisher;
import com.xiaotao.publisher.TopicPublisher;
import com.xiaotao.service.MerchantService;
import com.xiaotao.service.OrderService;
import com.xiaotao.util.ResponseEnum;
import com.xiaotao.util.ResponseUtil;
import com.xiaotao.util.SnowflakeIdGenerator;
import com.xiaotao.util.UserUtil;
import com.xiaotao.vo.TodayEarningVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.xiaotao.config.RabbitConfig.ORDER_CREATE_KEY;
import static com.xiaotao.config.RabbitConfig.ORDER_TTL;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private MerchantService merchantService;
    @Resource
    private GroupBuyMapper groupBuyMapper;
    @Resource
     private GoodsMapper goodsMapper;
    @Resource
    private WalletMapper walletMapper;
    @Resource
    private CouponMapper couponMapper;
    @Resource
    TopicPublisher topicPublisher;
    @Resource
    private CustomPublisher customPublisher;
    @Resource
    private PaymentLogMapper paymentLogMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private TypeMapper typeMapper;
    @Resource
    private MerchantMapper merchantMapper;

    @Override
    public ResponseUtil createOrderWithCoupon(OrderRequest req) throws Exception {
        SnowflakeIdGenerator sfg = new SnowflakeIdGenerator();
        String orderId = String.valueOf(sfg.nextId());

        BigDecimal totalAmount = BigDecimal.ZERO;
        List<OrderDetail> orderDetails = new ArrayList<>();

        // 计算商品金额
        for (GoodsDto item : req.getItems()) {
            Goods goods = goodsMapper.selectByPrimaryKey(item.getId());
            if (goods == null ) {
                throw new RuntimeException("商品无效或已下架: " + item.getName());
            }

            BigDecimal sub = goods.getPrice().multiply(BigDecimal.valueOf(item.getNum()));
            totalAmount = totalAmount.add(sub);

            OrderDetail d = new OrderDetail();
            d.setOrdersId(orderId);
            d.setGoodsId(goods.getId());
            d.setGoodsName(goods.getName());
            d.setGoodsPrice(goods.getPrice());
            d.setQuantity(item.getNum());
            d.setSubtotal(sub);
            orderDetails.add(d);
        }

        // 优惠券
        if (req.getCouponId() != null) {
            Coupon coupon = couponMapper.queryById(req.getCouponId());
            if (coupon != null) {
                totalAmount = totalAmount.multiply(coupon.getDiscount());
            }
        }

        Orders order = new Orders();
        order.setId(orderId);
        order.setUserId(req.getUserId());
        order.setMerchantId(req.getMerchantId());
        order.setTotalAmount(totalAmount);
        order.setOrderTime(new Date());
        order.setStatus((byte) 1);//

        // 延迟取消单逻辑
        customPublisher.send(orderId, ORDER_TTL);

        OrderDto dto = new OrderDto(order, orderDetails);
        topicPublisher.send(JSONObject.toJSONString(dto), ORDER_CREATE_KEY);

        return ResponseUtil.get(ResponseEnum.OK, dto);
    }
    @Override
    public ResponseUtil createGroupOrder(GroupBuyDto req) throws Exception {
        SnowflakeIdGenerator sfg = new SnowflakeIdGenerator();
        String orderId = String.valueOf(sfg.nextId());

        GroupBuy groupBuy = groupBuyMapper.selectByPrimaryKey(req.getId());
        if (groupBuy == null) {
            throw new RuntimeException("团购不存在或已下架");
        }

        Orders order = new Orders();
        order.setId(orderId);
        order.setMerchantId(req.getMerchantId());
        order.setGroupBuyId(req.getId());
        order.setTotalAmount(groupBuy.getDiscount());
        order.setOrderTime(new Date());
        order.setStatus((byte) 1);// 待支付

        // 团购固定商品明细
        List<OrderDetail> details = new ArrayList<>();
        for (GoodsDto goods : req.getGoodsList()) {
            OrderDetail d = new OrderDetail();
            d.setOrdersId(orderId);
            d.setGoodsId(goods.getId());
            d.setGoodsName(goods.getName());
            d.setGoodsPrice(goods.getPrice());
            d.setQuantity(1);
            d.setSubtotal(goods.getPrice());
            details.add(d);
        }

        // 发送延迟取消消息
        customPublisher.send(orderId, ORDER_TTL);

        OrderDto dto = new OrderDto(order, details);
        topicPublisher.send(JSONObject.toJSONString(dto), ORDER_CREATE_KEY);

        return ResponseUtil.get(ResponseEnum.OK, dto);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(String orderId)
    {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        if (orders == null) {
            throw new RuntimeException("订单不存在");
        }
        // 幂等：已取消或已支付跳过
        if (orders.getStatus() != 0) {
            return;
        }

        // 更新状态：2 = 已取消
        orders.setStatus((byte)2);
        orders.setCancelTime(new Date());
        ordersMapper.updateByPrimaryKeySelective(orders);

        // 退回优惠券
        if (orders.getCouponId() != null) {
            couponMapper.updateStatus(orders.getCouponId(), 0);
        }
        log.info("订单 {} 已自动取消", orderId);
    }
    @Override
    @Transactional
    public void paySuccess(String orderId, String tradeNo, BigDecimal amount, byte payType) {

        Orders order = ordersMapper.selectByPrimaryKey(orderId);
        if (order == null) throw new RuntimeException("订单不存在");

        // 幂等：如果已经支付成功，则直接返回
        if (order.getStatus() == 2){
            ResponseUtil.get(ResponseEnum.OK);
            return;
        }

        //  修改订单状态
        order.setStatus((byte)2);

        ordersMapper.updateByPrimaryKeySelective(order);

        //  写入支付日志
        paymentLogMapper.insertSelective(
                new PaymentLog(null, orderId, tradeNo, payType, amount, (byte)1, new Date(), new Date())
        );
        log.info("订单 {} 支付成功", orderId);
        //成功支付，支付金额写入redis累加
        String jsonStr = (String)redisTemplate.opsForValue().get("todayEarnings");
        if (jsonStr==null){
            //没有redis
            TodayEarningVo todayEarningVo = new TodayEarningVo();//新建一个空对象
            todayEarningVo.setTotalMoney(order.getTotalAmount());//设置值
            //根据订单查询抽佣比例
            Merchant merchant = merchantMapper.selectByPrimaryKey(order.getMerchantId());
            Type type = typeMapper.selectByPrimaryKey(merchant.getTypeId());
            todayEarningVo.setCommissionMoney(order.getTotalAmount().multiply(BigDecimal.valueOf(type.getScale() * 0.01)));
            String jsonString = JSON.toJSONString(todayEarningVo);
            redisTemplate.opsForValue().set("todayEarnings",jsonString);//放入redis
        }else {
            //存在，转换，拿到值累加
            TodayEarningVo o = JSON.parseObject(jsonStr, TodayEarningVo.class);
            o.setTotalMoney(o.getTotalMoney().add(order.getTotalAmount()));//累加
            //根据订查询抽佣比例
            Merchant merchant = merchantMapper.selectByPrimaryKey(order.getMerchantId());
            Type type = typeMapper.selectByPrimaryKey(merchant.getTypeId());
            o.setCommissionMoney(o.getCommissionMoney().add(order.getTotalAmount().multiply(BigDecimal.valueOf(type.getScale() * 0.01))));
            String jsonString = JSON.toJSONString(o);//将对象转未json字符串
            redisTemplate.opsForValue().set("todayEarnings",jsonString);
        }
    }

    @Override
    public ResponseUtil verifyOrder(String orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        return ResponseUtil.get(ResponseEnum.OK, orders);
    }

    @Override
    public ResponseUtil queryAll() {
        List<Orders> orders = ordersMapper.selectAll();
        return ResponseUtil.get(ResponseEnum.OK, orders);
    }

    @Override
    public ResponseUtil delete(String orderId) {
        int i = ordersMapper.deleteByPrimaryKey(orderId);
        return i > 0 ? ResponseUtil.get(ResponseEnum.OK) : ResponseUtil.get(ResponseEnum.FAIL);
    }

    @Override
    public ResponseUtil update(Orders orders) {
        int i = ordersMapper.updateByPrimaryKey(orders);
        return i > 0 ? ResponseUtil.get(ResponseEnum.OK) : ResponseUtil.get(ResponseEnum.FAIL);
    }


}







